
package com.frame.detection.controller;

import com.frame.detection.client.ImageDetectClient;
import com.frame.detection.constants.ViewModelConstants;
import com.frame.detection.service.ImageConsultService;
import com.frame.detection.service.ImageDetectService;
import com.frame.detection.service.Select_algorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletResponse;
import javax.xml.crypto.Data;
import java.io.*;
import java.net.URLEncoder;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Controller
public class ImageDetectController {

    /**
     * logger of ImageDetectController
     */
    private Logger logger = LoggerFactory.getLogger(ImageDetectController.class);

    /**
     * service of imageDetect
     */
    @Autowired
    private ImageDetectService imageDetectService;

    @Autowired
    private Select_algorithm select_fun;

    @Autowired
    private ImageDetectClient imageDetectClient;

    /**
     * service of imageConsult
     */
    @Autowired
    private ImageConsultService imageConsultService;

//    public ImageDetectController(Select_algorithm select_fun) {
//        this.select_fun = select_fun;
//    }

    /**
     * detect out
     *
     * @return
     */

    @RequestMapping(value = "/detect", method = RequestMethod.GET)
    public String detect() {

        return ViewModelConstants.DETECT;
    }

    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public String test() {

        return "dashboard";
    }

    @RequestMapping(value = "/test_i", method = RequestMethod.GET)
    public String test_i() {

        return "icons";
    }


    /**
     * detect out
     *
     * @param
     * @return
     */

    @RequestMapping(value = "/all_contrast", method = RequestMethod.POST)
    public ModelAndView All(String radio1) throws IOException {
        System.out.println("*******************");
        System.out.println("算法对比......");
        System.out.println("选择对比图："+radio1);

        String imgURL = "";
        String clearURL = "";
        if (radio1.equals("1")) {
            imgURL = "E:\\A_code\\Projects\\DLP\\DeepLearning\\image\\haze\\0023_0.85_0.12_2.jpg";
            clearURL="E:\\A_code\\Projects\\DLP\\DeepLearning\\image\\clear\\0023_2.png";
        } else if (radio1.equals("2")) {
            imgURL = "E:\\A_code\\Projects\\DLP\\DeepLearning\\image\\haze\\0098_0.85_0.2_2.jpg";
            clearURL="E:\\A_code\\Projects\\DLP\\DeepLearning\\image\\clear\\0098_2.png";
        } else if (radio1.equals("3")) {
            imgURL = "E:\\A_code\\Projects\\DLP\\DeepLearning\\image\\haze\\1909_0.85_0.2_2.jpg";
            clearURL="E:\\A_code\\Projects\\DLP\\DeepLearning\\image\\clear\\1909_2.png";
        } else {
            imgURL = "E:\\A_code\\Projects\\DLP\\DeepLearning\\image\\haze\\1_2.png";
            clearURL="E:\\A_code\\Projects\\DLP\\DeepLearning\\image\\clear\\1_2.jpg";
        }
//        模拟前端上传的文件，file类型转换为multipartFile类型
        File file = new File(imgURL);
        FileInputStream contentStream = new FileInputStream(file);
        MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getName(), MediaType.APPLICATION_OCTET_STREAM_VALUE, contentStream);

        File file_c = new File(clearURL);
        FileInputStream contentStream_c = new FileInputStream(file_c);
        MultipartFile multipartFile_c = new MockMultipartFile(file_c.getName(), file_c.getName(), MediaType.APPLICATION_OCTET_STREAM_VALUE, contentStream_c);



        String imageLink = null;
        MultipartFile imageFile = multipartFile;
        MultipartFile imageFile_c = multipartFile_c;

        BASE64Encoder base64Encoder = new BASE64Encoder();
        String img_clear = base64Encoder.encode(imageFile_c.getBytes());

        //  获取原始有雾图片
        String detectOut_h = select_fun.fun_Original(imageLink, imageFile);



        //  图像去雾
        Date time_aodnet_start=new Date();
        double start_A=time_aodnet_start.getTime();
        String detectOut_A = select_fun.fun_haze_A(imageLink, imageFile);
        Date time_aodnet_end=new Date();
        double end_A=time_aodnet_end.getTime();
        double time_A=(end_A-start_A)/1000;

        String detectOut_G = select_fun.fun_haze_G(imageLink, imageFile);
        Date time_GCANet_end=new Date();
        double end_G=time_GCANet_end.getTime();
        double time_G=(end_G-end_A)/1000;

        String detectOut_F = select_fun.fun_haze_F(imageLink, imageFile);
        Date time_FFANet_end=new Date();
        double end_F=time_FFANet_end.getTime();
        double time_F=(end_F-end_G)/1000;


//        获取psnr
        MultiValueMap<String, String> paramMap_a = new LinkedMultiValueMap<>();
        paramMap_a.add("psnr", "AODNet_psnr");
        paramMap_a.add("select", radio1);
        String aodnet_psnr = imageDetectClient.getDetectImagePost_psnr(paramMap_a);
        System.out.println(aodnet_psnr);

        MultiValueMap<String, String> paramMap_g = new LinkedMultiValueMap<>();
        paramMap_g.add("psnr", "GCANet_psnr");
        paramMap_g.add("select", radio1);
        String gcanet_psnr = imageDetectClient.getDetectImagePost_psnr(paramMap_g);
        System.out.println(gcanet_psnr);

        MultiValueMap<String, String> paramMap_f = new LinkedMultiValueMap<>();
        paramMap_f.add("psnr", "FFA_psnr");
        paramMap_f.add("select", radio1);
        String ffa_psnr = imageDetectClient.getDetectImagePost_psnr(paramMap_f);
        System.out.println(ffa_psnr);

//        获取ssim
        MultiValueMap<String, String> paramMap_a_s = new LinkedMultiValueMap<>();
        paramMap_a_s.add("ssim", "AODNet_ssim");
        paramMap_a_s.add("select", radio1);
        String aodnet_ssim = imageDetectClient.getDetectImagePost_ssim(paramMap_a_s);
        System.out.println(aodnet_ssim);

        MultiValueMap<String, String> paramMap_g_s = new LinkedMultiValueMap<>();
        paramMap_g_s.add("ssim", "GCANet_ssim");
        paramMap_g_s.add("select", radio1);
        String gcanet_ssim = imageDetectClient.getDetectImagePost_ssim(paramMap_g_s);
        System.out.println(gcanet_ssim);

        MultiValueMap<String, String> paramMap_f_s = new LinkedMultiValueMap<>();
        paramMap_f_s.add("ssim", "FFA_ssim");
        paramMap_f_s.add("select", radio1);
        String ffa_ssim = imageDetectClient.getDetectImagePost_ssim(paramMap_f_s);
        System.out.println(ffa_ssim);


//视图与数据
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("cd");
        modelAndView.addObject("AODNet_psnr", aodnet_psnr);
        modelAndView.addObject("GCANet_psnr", gcanet_psnr);
        modelAndView.addObject("FFA_psnr", ffa_psnr);

        modelAndView.addObject("AODNet_ssim", aodnet_ssim);
        modelAndView.addObject("GCANet_ssim", gcanet_ssim);
        modelAndView.addObject("FFA_ssim", ffa_ssim);

        modelAndView.addObject(ViewModelConstants.DETECT_OUT_IMAGE_h, detectOut_h);
        modelAndView.addObject("img_A", detectOut_A);
        modelAndView.addObject("img_G", detectOut_G);
        modelAndView.addObject("img_F", detectOut_F);
        modelAndView.addObject("img_clear", img_clear);


        modelAndView.addObject("time_A",time_A);
        modelAndView.addObject("time_G",time_G);
        modelAndView.addObject("time_F",time_F);


        return modelAndView;
    }

    @RequestMapping(value = "/detectImage", method = RequestMethod.POST)
    public ModelAndView detectOut(String imageLink, MultipartFile imageFile, String[] algorithm) {
//    public  String detectOut(String options, String imageLink, MultipartFile imageFile) {

        List list = new ArrayList();
        for (int i = 0; i < algorithm.length; i++) {
            list.add(algorithm[i]);
            System.out.println("select: " + algorithm[i]);
        }

        System.out.println("select numbers :" + algorithm.length);
        System.out.println("imageLink :" + imageLink);
        System.out.println("imageFile :" + imageFile);
        System.out.println("**************");

        // assemble modelAndView
        ModelAndView modelAndView = new ModelAndView();


        int flage = -1;
        if (list.size() == 1) {
            if (list.get(0).equals("AOD_Net")) {
                flage = 1;

                //        获取原始有雾图片
                String detectOut_h = select_fun.fun_Original(imageLink, imageFile);

                Date start=new Date();
                double startTime=start.getTime();
                System.out.println("starttime: "+startTime);

                //  dehazing image
                String detectOut_A = select_fun.fun_haze_A(imageLink, imageFile);

                Date end=new Date();
                double endTime=end.getTime();
                System.out.println("endTime: "+endTime);
                double runTime=(endTime-startTime)/1000;
                System.out.println("runTime: "+runTime);

                modelAndView.setViewName("detectOut_AOD_Net");
                modelAndView.addObject(ViewModelConstants.DETECT_OUT_IMAGE_h, detectOut_h);
                modelAndView.addObject("img_A", detectOut_A);
                modelAndView.addObject("time_A",runTime);

                return modelAndView;

            } else if (list.get(0).equals("GCANet")) {
                flage = 2;

                //        获取原始有雾图片
                String detectOut_h = select_fun.fun_Original(imageLink, imageFile);

                Date time=new Date();
                double startTime=time.getTime();
                System.out.println("starttime: "+startTime);

                //  dehazing image
                String detectOut_G = select_fun.fun_haze_G(imageLink, imageFile);

                Date end=new Date();
                double endTime=end.getTime();
                System.out.println("endTime: "+endTime);
                double runTime=(endTime-startTime)/1000;
                System.out.println(runTime);

                modelAndView.setViewName("detectOut_GCANet");
                modelAndView.addObject(ViewModelConstants.DETECT_OUT_IMAGE_h, detectOut_h);
                modelAndView.addObject("img_G", detectOut_G);
                modelAndView.addObject("time_G",runTime);

                return modelAndView;
            } else if (list.get(0).equals("FFA")) {
                flage = 3;

                //        获取原始有雾图片
                String detectOut_h = select_fun.fun_Original(imageLink, imageFile);

                Date time=new Date();
                double startTime=time.getTime();
                System.out.println("starttime: "+startTime);

                //  dehazing image
                String detectOut_F = select_fun.fun_haze_F(imageLink, imageFile);

                Date end=new Date();
                double endTime=end.getTime();
                System.out.println("endTime: "+endTime);
                double runTime=(endTime-startTime)/1000;
                System.out.println(runTime);

                modelAndView.setViewName("detectOut_FFA");
                modelAndView.addObject(ViewModelConstants.DETECT_OUT_IMAGE_h, detectOut_h);
                modelAndView.addObject("img_F", detectOut_F);
                modelAndView.addObject("time_F",runTime);

                return modelAndView;
            }
        } else if (list.size() == 2) {
            if (list.get(0).equals("AOD_Net")) {
                if (list.get(1).equals("GCANet")) {
                    flage = 4;

                    //        获取原始有雾图片
                    String detectOut_h = select_fun.fun_Original(imageLink, imageFile);

                    //  dehazing image
                    Date time=new Date();
                    double startTime=time.getTime();
                    String detectOut_A = select_fun.fun_haze_A(imageLink, imageFile);
                    Date end=new Date();
                    double endTime=end.getTime();
                    double runTime_A=(endTime-startTime)/1000;
                    System.out.println(runTime_A);

                    String detectOut_G = select_fun.fun_haze_G(imageLink, imageFile);
                    Date end_G=new Date();
                    double endTime_G=end_G.getTime();
                    double runTime_G=(endTime_G-endTime)/1000;
                    System.out.println(runTime_G);

                    modelAndView.setViewName("detectOut_AG");
                    modelAndView.addObject(ViewModelConstants.DETECT_OUT_IMAGE_h, detectOut_h);
                    modelAndView.addObject("img_A", detectOut_A);
                    modelAndView.addObject("img_G", detectOut_G);
                    modelAndView.addObject("time_A",runTime_A);
                    modelAndView.addObject("time_G",runTime_G);

                    return modelAndView;
                } else if (list.get(1).equals("FFA")) {
                    flage = 5;

                    //        获取原始有雾图片
                    String detectOut_h = select_fun.fun_Original(imageLink, imageFile);

                    //  dehazing image
                    Date time=new Date();
                    double startTime=time.getTime();
                    String detectOut_A = select_fun.fun_haze_A(imageLink, imageFile);
                    Date end=new Date();
                    double endTime=end.getTime();
                    double runTime_A=(endTime-startTime)/1000;
                    System.out.println(runTime_A);

                    String detectOut_F = select_fun.fun_haze_F(imageLink, imageFile);
                    Date end_F=new Date();
                    double endTime_F=end_F.getTime();
                    double runTime_F=(endTime_F-endTime)/1000;
                    System.out.println(runTime_F);

                    modelAndView.setViewName("detectOut_AF");
                    modelAndView.addObject(ViewModelConstants.DETECT_OUT_IMAGE_h, detectOut_h);
                    modelAndView.addObject("img_A", detectOut_A);
                    modelAndView.addObject("img_F", detectOut_F);
                    modelAndView.addObject("time_A",runTime_A);
                    modelAndView.addObject("time_F",runTime_F);

                    return modelAndView;
                }
            } else {
                flage = 6;

                //        获取原始有雾图片
                String detectOut_h = select_fun.fun_Original(imageLink, imageFile);

                //  dehazing image
                Date time=new Date();
                double startTime=time.getTime();
                String detectOut_G = select_fun.fun_haze_G(imageLink, imageFile);
                Date end=new Date();
                double endTime=end.getTime();
                double runTime_G=(endTime-startTime)/1000;
                System.out.println(runTime_G);

                String detectOut_F = select_fun.fun_haze_F(imageLink, imageFile);
                Date end_F=new Date();
                double endTime_F=end_F.getTime();
                double runTime_F=(endTime_F-endTime)/1000;
                System.out.println(runTime_F);

                modelAndView.setViewName("detectOut_GF");
                modelAndView.addObject(ViewModelConstants.DETECT_OUT_IMAGE_h, detectOut_h);
                modelAndView.addObject("img_G", detectOut_G);
                modelAndView.addObject("img_F", detectOut_F);
                modelAndView.addObject("time_G",runTime_G);
                modelAndView.addObject("time_F",runTime_F);

                return modelAndView;
            }
        } else {
            flage = 7;

            //        获取原始有雾图片
            String detectOut_h = select_fun.fun_Original(imageLink, imageFile);
            //  dehazing image
            Date time=new Date();
            double startTime=time.getTime();
            String detectOut_A = select_fun.fun_haze_A(imageLink, imageFile);
            Date end_A=new Date();
            double endTime_A=end_A.getTime();
            double runTime_A=(endTime_A-startTime)/1000;
            System.out.println(runTime_A);


            String detectOut_G = select_fun.fun_haze_G(imageLink, imageFile);
            Date end_G=new Date();
            double endTime_G=end_G.getTime();
            double runTime_G=(endTime_G-endTime_A)/1000;
            System.out.println(runTime_G);

            String detectOut_F = select_fun.fun_haze_F(imageLink, imageFile);
            Date end_F=new Date();
            double endTime_F=end_F.getTime();
            double runTime_F=(endTime_F-endTime_G)/1000;
            System.out.println(runTime_F);

            modelAndView.setViewName("detectOut_AGF");
            modelAndView.addObject(ViewModelConstants.DETECT_OUT_IMAGE_h, detectOut_h);
            modelAndView.addObject("img_A", detectOut_A);
            modelAndView.addObject("img_G", detectOut_G);
            modelAndView.addObject("img_F", detectOut_F);
            modelAndView.addObject("time_A",runTime_A);
            modelAndView.addObject("time_G",runTime_G);
            modelAndView.addObject("time_F",runTime_F);

            return modelAndView;
        }

//         step 3. return detect result page
        return modelAndView;
    }


    /**
     * detect image whit redis cache
     *
     * @return
     */
    @RequestMapping(value = "/detectWithCache", method = RequestMethod.GET)
    public String detectWithCache() {

        return ViewModelConstants.DETECT_CONSULT;
    }

    /**
     * detect out with redis cache
     *
     * @param imageLink
     * @return
     */
    @RequestMapping(value = "/detectOutWithCache", method = RequestMethod.POST)
    public ModelAndView detectOutWithCache(String imageLink) throws Exception {

        // step 1. detect image
        String detectOut = imageConsultService.detectInQueue(imageLink);


        // step 2. assemble modelAndView
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName(ViewModelConstants.DETECT_OUT);
        modelAndView.addObject(ViewModelConstants.DETECT_OUT_IMAGE, detectOut);

        // step 3. return detect result page
        return modelAndView;
    }

}